#include "EasyHookLib.h"
#include "MinHook.h"

namespace EasyHook
{

// HookManager单例实现
HookManager &HookManager::getInstance()
{
    static HookManager instance;
    return instance;
}

// HookManager析构函数
HookManager::~HookManager()
{
    cleanup();
}

// 初始化Hook系统
bool HookManager::initialize()
{
    if (initialized_)
    {
        return true;
    }

    MH_STATUS status = MH_Initialize();
    if (status != MH_OK)
    {
        setError("Failed to initialize MinHook: " + statusToString(status));
        return false;
    }

    initialized_ = true;
    return true;
}

// 清理Hook系统
bool HookManager::cleanup()
{
    if (!initialized_)
    {
        return true;
    }

    // 禁用所有Hook
    disableAllHooks();

    // 清理MinHook
    MH_STATUS status = MH_Uninitialize();
    if (status != MH_OK)
    {
        setError("Failed to uninitialize MinHook: " + statusToString(status));
        return false;
    }

    initialized_ = false;
    hooks_.clear();
    return true;
}

// 通过函数名创建Hook（用于系统API）
bool HookManager::createAPIHook(const std::string &moduleName, const std::string &funcName, LPVOID detourFunc, LPVOID *originalFunc)
{
    if (!initialized_ && !initialize())
    {
        return false;
    }

    // 转换字符串为宽字符
    std::wstring wModuleName(moduleName.begin(), moduleName.end());

    MH_STATUS status = MH_CreateHookApi(wModuleName.c_str(), funcName.c_str(), detourFunc, originalFunc);

    if (status != MH_OK)
    {
        setError("Failed to create API hook for " + moduleName + "::" + funcName + ": " + statusToString(status));
        return false;
    }

    HMODULE hModule = GetModuleHandleA(moduleName.c_str());
    if (hModule)
    {
        LPVOID targetFunc = GetProcAddress(hModule, funcName.c_str());
        if (targetFunc)
        {
            status = MH_EnableHook(targetFunc);
            if (status != MH_OK)
            {
                setError("Failed to enable API hook: " + statusToString(status));
                return false;
            }
            hooks_.push_back(targetFunc);
        }
    }

    return true;
}

// 启用所有Hook
bool HookManager::enableAllHooks()
{
    MH_STATUS status = MH_EnableHook(MH_ALL_HOOKS);
    if (status != MH_OK)
    {
        setError("Failed to enable all hooks: " + statusToString(status));
        return false;
    }
    return true;
}

// 禁用所有Hook
bool HookManager::disableAllHooks()
{
    MH_STATUS status = MH_DisableHook(MH_ALL_HOOKS);
    if (status != MH_OK)
    {
        setError("Failed to disable all hooks: " + statusToString(status));
        return false;
    }
    return true;
}

// 获取最后的错误信息
std::string HookManager::getLastError() const
{
    return lastError_;
}

// 设置错误信息
void HookManager::setError(const std::string &error)
{
    lastError_ = error;
}

// 状态码转字符串
std::string HookManager::statusToString(int status)
{
    switch (status)
    {
    case MH_OK:
        return "MH_OK";
    case MH_ERROR_ALREADY_INITIALIZED:
        return "MH_ERROR_ALREADY_INITIALIZED";
    case MH_ERROR_NOT_INITIALIZED:
        return "MH_ERROR_NOT_INITIALIZED";
    case MH_ERROR_ALREADY_CREATED:
        return "MH_ERROR_ALREADY_CREATED";
    case MH_ERROR_NOT_CREATED:
        return "MH_ERROR_NOT_CREATED";
    case MH_ERROR_ENABLED:
        return "MH_ERROR_ENABLED";
    case MH_ERROR_DISABLED:
        return "MH_ERROR_DISABLED";
    case MH_ERROR_NOT_EXECUTABLE:
        return "MH_ERROR_NOT_EXECUTABLE";
    case MH_ERROR_UNSUPPORTED_FUNCTION:
        return "MH_ERROR_UNSUPPORTED_FUNCTION";
    case MH_ERROR_MEMORY_ALLOC:
        return "MH_ERROR_MEMORY_ALLOC";
    case MH_ERROR_MEMORY_PROTECT:
        return "MH_ERROR_MEMORY_PROTECT";
    case MH_ERROR_MODULE_NOT_FOUND:
        return "MH_ERROR_MODULE_NOT_FOUND";
    case MH_ERROR_FUNCTION_NOT_FOUND:
        return "MH_ERROR_FUNCTION_NOT_FOUND";
    default:
        return "Unknown error";
    }
}

// ================================
// 新增：扩展功能实现
// ================================

// 通过偏移获取地址
LPVOID HookManager::GetAddressByOffset(const std::string &moduleName, DWORD offset)
{
    HMODULE hModule = GetModuleHandleA(moduleName.c_str());
    if (!hModule)
    {
        setError("Failed to get module handle for: " + moduleName);
        return nullptr;
    }

    return reinterpret_cast<LPVOID>(reinterpret_cast<uintptr_t>(hModule) + offset);
}

// 通过函数名获取地址
LPVOID HookManager::GetFunctionAddress(const std::string &moduleName, const std::string &functionName)
{
    HMODULE hModule = GetModuleHandleA(moduleName.c_str());
    if (!hModule)
    {
        setError("Failed to get module handle for: " + moduleName);
        return nullptr;
    }

    LPVOID funcAddr = GetProcAddress(hModule, functionName.c_str());
    if (!funcAddr)
    {
        setError("Failed to get function address for: " + moduleName + "::" + functionName);
        return nullptr;
    }

    return funcAddr;
}

// 通过偏移创建Hook
bool HookManager::createOffsetHook(const std::string &moduleName, DWORD offset, LPVOID detourFunc, LPVOID *originalFunc)
{
    if (!initialized_ && !initialize())
    {
        return false;
    }

    // 获取目标地址
    LPVOID targetAddr = GetAddressByOffset(moduleName, offset);
    if (!targetAddr)
    {
        return false;
    }

    // 创建Hook
    MH_STATUS status = MH_CreateHook(targetAddr, detourFunc, originalFunc);
    if (status != MH_OK)
    {
        setError("Failed to create offset hook for " + moduleName + "+0x" + std::to_string(offset) + ": " + statusToString(status));
        return false;
    }

    // 启用Hook
    status = MH_EnableHook(targetAddr);
    if (status != MH_OK)
    {
        setError("Failed to enable offset hook: " + statusToString(status));
        return false;
    }

    hooks_.push_back(targetAddr);
    return true;
}

} // namespace EasyHook